An Extended Debugging Session

This section illustrates use of the Scheme debug procedure in an extended session. The first example is the buggy fact procedure that was used as an example in section [*] above. The sequence begins with the interaction already described in section [*].


\begin{scheme}
\par
[1 REP] (define (fact n)
(if (zero? n)
l
(* n (fact (-1+ ...
...ber: 0
Expression:
L
within Procedure FACT
applied to (0)
\par
\end{scheme}
The command S displays the current subproblem. The command B moves backwards in time.
\begin{scheme}[3 Debug]b
Subproblem Level: 0 Reduction Number: 1
Expression:
...
...
(* N (FACT (-1+ N)))
within Procedure FACT
applied to (1)
\par
\end{scheme}
The F command moves forward through reductions one at a time, in the opposite direction to B.
\begin{scheme}[3 Debug]f
Subproblem Level: 0 Reduction Number: 2
Expression:
...
...ber: 0
Expression:
L
within Procedure FACT
applied to (0)
\par
\end{scheme}
We are now back at the subproblem level containing the offending expression. The variable L is unbound. The Z (for ZAP) command asks for an expression to evaluate and returns this value as the value of the current subproblem to the previous subproblem, that is, the containing subproblem. Here we wanted L to be 1.
\begin{scheme}[3 Debug]z
Enter an expression to EVALUATE and CONTINUE with: 1
That evaluates to:
\par
1
Confirm: [Y or N] -> y
6
\par
\end{scheme}
And here is the correct result. Let's look at another example:
\begin{scheme}
\par
[1 REP] (define (square-root x)
(define (square-root-iter a...
...(- (* ANS ASN) X)) .0001)
within Procedure CLOSE?
applied to (1)
\end{scheme}
Above is a square root program that is divided into sub-procedures. In the program there is a bug. The debugger was called to reveal that the unbound variable ASN is in the expression (* ans asn) in the procedure CLOSE?.

Here is another example:


\begin{scheme}[1 REP](define (sum term low high)
(define (sum-iter sum index)
...
...TERM INDEX))
4 SUM-ITER (SUM-ITER (+ SUM (TERM INDEX)) (1+ INDEX))
\end{scheme}

The bug here is that the procedure EVEN? was spelled EVIN?, in the definition of the procedure TERM-PROC. By looking at the history we can see that the procedure SUM was called somewhere at subproblem 4. The command G used below goes to a specified subproblem and reduction. Below we see the call to SUM in subproblem 4, reduction 4.


\begin{scheme}[3 Debug]g
Subproblem number: 4
Reduction Number (0 through 4 i...
...ROCEDURE SUM>
TERM-PROC = \char93 {}<COMPOUND-PROCEDURE TERM-PROC>
\end{scheme}
The environment in which subproblem 4 was being evaluated is the user-initial-environment. The C command displayes the variable bindings in the evaluation environment of the current subproblem. Which in this case is the user-initial-environment. This is where evin? should be defined. The V command evaluates an expression in the current environment.


\begin{scheme}[3 Debug]v
[3 Eval] (define evin? even?)
EVIN?
\par
[3 Debug] c...
...UND-PROCEDURE EVEN?>
\par
[3 Debug] q
\par
[2 Error] (proceed)
2
\end{scheme}

Above we defined the variable evin? to have as its value the procedure even?. We then left the debugger. By typing (proceed) at the error prompt we cause the program to continue with the evaluation of the expression that caused the error, and the procedure completes returning the correct answer.